/// Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VSPowerToys.Common.TaskManager.ContentInstaller;
using NUnit.Framework;
using System.IO;

namespace Microsoft.VSPowerToys.Common.TaskManager.Tests
{
    /// <summary>
    /// Contains test cases for content installer functionality
    /// </summary>
    [TestFixture]
    public class ContentInstallerTests
    {

        /// <summary>
        /// Gets the path for test content files
        /// </summary>
        private static string TestContentsPath
        {
            get { return Path.Combine(Environment.CurrentDirectory, @"..\..\TestContents\"); }
        }

        #region VSContent file tests

        /// <summary>
        /// Verifies a vscontent file with all valid content files can be read correctly.
        /// </summary>
        [Test]
        public void TestValidContentFile()
        {
            VsiPackage package = new VsiPackage();
            bool result = package.ReadVSContentFile(Path.Combine(TestContentsPath, "ValidAllTypes.vscontent"));
            Assert.IsTrue(result, Strings.ContentFileNotReadable);
            Assert.AreEqual(4, package.Contents.Count, Strings.InvalidNumberOfContents);
        }

        /// <summary>
        /// Tests an invalid snippet content with an unknown language
        /// </summary>
        [Test]
        public void TestSnippetInvalidLanguage()
        {
            VsiPackage package = new VsiPackage();
            bool result = package.ReadVSContentFile(Path.Combine(TestContentsPath, "InvalidLanguageSnippet.vscontent"));
            Assert.IsTrue(result, Strings.ContentFileNotReadable);
            Assert.AreEqual(0, package.Contents.Count, Strings.InvalidNumberOfContents);
        }

        /// <summary>
        /// Tests an invalid template content with an unknown type
        /// </summary>
        [Test]
        public void TestTemplateInvalidType()
        {
            VsiPackage package = new VsiPackage();
            bool result = package.ReadVSContentFile(Path.Combine(TestContentsPath, "InvalidTemplateType.vscontent"));
            Assert.IsTrue(result, Strings.ContentFileNotReadable);
            Assert.AreEqual(0, package.Contents.Count, Strings.InvalidNumberOfContents);
        }

        /// <summary>
        /// Tests an invalid content entry with version number 1.1
        /// </summary>
        [Test]
        public void TestInvalidVersion()
        {
            VsiPackage package = new VsiPackage();
            bool result = package.ReadVSContentFile(Path.Combine(TestContentsPath, "InvalidVersionContent.vscontent"));
            Assert.IsTrue(result, Strings.ContentFileNotReadable);
            Assert.AreEqual(0, package.Contents.Count, Strings.InvalidNumberOfContents);
        }

        /// <summary>
        /// Tests a valid snippet file for content information
        /// </summary>
        [Test]
        public void TestContentInformation()
        {
            VsiPackage package = new VsiPackage();
            bool result = package.ReadVSContentFile(Path.Combine(TestContentsPath, "ValidSnippet.vscontent"));
            Assert.IsTrue(result, Strings.ContentFileNotReadable);
            Assert.AreEqual(1, package.Contents.Count, Strings.InvalidNumberOfContents);
            BaseVSContent content = package.Contents[0];
            Assert.AreEqual("Test Snippet", content.DisplayName);
            Assert.AreEqual("Test Description", content.Description);
            Assert.AreEqual(1, content.FileNames.Count);
            Assert.AreEqual("Test.snippet", content.FileNames[0]);
            Assert.AreEqual("CSharp", content.Attributes["lang"]);
        }

        #endregion

        #region VSI Install Task tests

        /// <summary>
        /// Tests to verify if a snippet content is installed successfully.
        /// </summary>
        [Test]
        public void TestSnippetInstallVSI()
        {
            InstallVsiTask installTask = new InstallVsiTask(Path.Combine(TestContentsPath, "PackInstallerUnitTests.vsi"), true);
            installTask.PerformTask();
            string targetFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
                    @"Visual Studio 2005\Code Snippets\Visual C#\My Code Snippets\PackInstallerUnitTests.snippet");
            Assert.IsTrue(File.Exists(targetFile), Strings.InstalledFileNotFound);
            File.Delete(targetFile);
        }

        /// <summary>
        /// Tests to verify if a snippet content is installed successfully from vscontent file
        /// </summary>
        [Test]
        public void TestSnippetInstallContentFile()
        {
            string testFile = Path.Combine(TestContentsPath, "PackInstallerUnitTests.snippet");
            File.SetAttributes(testFile, FileAttributes.Normal);
            InstallVsiTask installTask = new InstallVsiTask(Path.Combine(TestContentsPath, "TestSnippet.vscontent"), false);
            installTask.PerformTask();
            string targetFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
                    @"Visual Studio 2005\Code Snippets\Visual C#\My Code Snippets\PackInstallerUnitTests.snippet");
            Assert.IsTrue(File.Exists(targetFile), Strings.InstalledFileNotFound);
            File.Delete(targetFile);
        }

        /// <summary>
        /// Tests to verify if a invalid VSI files are handled correctly (Invalid zip files)
        /// </summary>
        [Test]
        public void TestInvalidVSIFile()
        {
            InstallVsiTask installTask = new InstallVsiTask(Path.Combine(TestContentsPath, "TestSnippet.vscontent"), true);
            try
            {
                installTask.PerformTask();
                Assert.Fail("No error was reported in an invalid test case");
            }
            catch (TaskException)
            {
            }
        }
        #endregion

        [Test]
        public void VsiExceptionUnitTests()
        {
            VsiPackage package = new VsiPackage();
            bool result = package.ReadVSContentFile(Path.Combine(TestContentsPath, "ValidSnippet.vscontent"));
            Assert.IsTrue(result, Strings.ContentFileNotReadable);
            Assert.AreEqual(1, package.Contents.Count, Strings.InvalidNumberOfContents);
            BaseVSContent content = package.Contents[0];

            VsiException testException = new VsiException();
            testException = new VsiException("VsiExceptionUnitTests");
            testException = new VsiException("VsiExceptionUnitTests", new System.AccessViolationException());

            testException = new VsiException(content);
            Assert.AreEqual(content, testException.Content, "Content is incorrect.");

            testException = new VsiException("VsiExceptionUnitTests", content);
            Assert.AreEqual(content, testException.Content, "Content is incorrect.");

            testException = new VsiException("VsiExceptionUnitTests", new System.AccessViolationException(), content);
            Assert.AreEqual(content, testException.Content, "Content is incorrect.");

        }
    }
}
